using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
using System.Collections.Concurrent;
using hao_Common.Logging.Extensions;
using hao_Common.Logging.Helpers;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;

var builder = WebApplication.CreateBuilder(args);

// 配置Serilog日志
builder.Host.AddSerilog(builder.Configuration);

// 添加日志服务
builder.Services.AddLogging(builder.Configuration);

// 添加CORS，允许前端H5开发端访问
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowFrontend", policy =>
    {
        policy.WithOrigins(
            "http://localhost:8080",
            "http://127.0.0.1:8080"
        )
        .AllowAnyHeader()
        .AllowAnyMethod();
    });
});

// 配置URL
var configuration = builder.Configuration;
var serverUrl = configuration["hao-Chat.Api:ServerUrl"] ?? "http://localhost:8083";
Console.WriteLine($"Chat API 启动端口: {serverUrl}");
builder.WebHost.UseUrls(serverUrl);

var app = builder.Build();

// 获取日志器
var logger = app.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Chat API 服务启动");

// 数据存储
var users = new ConcurrentDictionary<string, User>(); // UserId -> User
var userConnections = new ConcurrentDictionary<string, User>(); // ConnectionId -> User
var groups = new ConcurrentDictionary<string, Group>(); // GroupId -> Group
var userIdCounter = 100000; // 账号从100000开始

// Redis 初始化
var redisConnStr = configuration["Redis:ConnectionString"] ?? "localhost:6379";
var redis = ConnectionMultiplexer.Connect(redisConnStr);
var redisDb = redis.GetDatabase();

string GetHistoryKey(string a, string b)
{
    if (string.CompareOrdinal(a, b) <= 0)
        return $"chat:history:{a}:{b}";
    return $"chat:history:{b}:{a}";
}

string GetRecentKey(string userId) => $"chat:recent:{userId}";
string GetUnreadHashKey(string userId) => $"chat:unread:{userId}";
string GetLatestKey(string a, string b)
{
    if (string.CompareOrdinal(a, b) <= 0)
        return $"chat:latest:{a}:{b}";
    return $"chat:latest:{b}:{a}";
}

// 静态文件服务
app.UseDefaultFiles();
app.UseStaticFiles();
// 启用CORS（需在映射端点之前）
app.UseCors("AllowFrontend");
app.UseWebSockets();

// WebSocket端点
app.Map("/ws", async context =>
{
    if (context.WebSockets.IsWebSocketRequest)
    {
        var webSocket = await context.WebSockets.AcceptWebSocketAsync();
        
        // 从查询参数获取userId作为连接ID
        var userId = context.Request.Query["userId"].FirstOrDefault();
        //当前连接的用户id 如果没有提供userId，则生成一个临时连接ID
        var connectionId = !string.IsNullOrEmpty(userId) ? userId : Guid.NewGuid().ToString();
        
        logger.LogBusinessOperation("新WebSocket连接建立", new { 
            ConnectionId = connectionId,
            ProvidedUserId = userId,
            ClientIP = context.Connection.RemoteIpAddress?.ToString()
        });
        Console.WriteLine($"新连接用户: {connectionId}");
        await HandleWebSocketConnection(webSocket, connectionId);
    }
    else
    {
        logger.LogWarning("非WebSocket请求尝试连接WebSocket端点");
        context.Response.StatusCode = 400;
    }
});

// 处理WebSocket连接
async Task HandleWebSocketConnection(WebSocket webSocket, string connectionId)
{
    var buffer = new byte[1024 * 4];
    
    try
    {
        while (webSocket.State == WebSocketState.Open)
        {
            var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            
            if (result.MessageType == WebSocketMessageType.Text)
            {
                var messageText = Encoding.UTF8.GetString(buffer, 0, result.Count);
                logger.LogInformation("收到WebSocket消息: {ConnectionId}, 消息长度: {Length}", connectionId, messageText.Length);
                Console.WriteLine($"[DEBUG] 收到消息: {messageText}");
                Console.WriteLine($"[DEBUG] 连接ID: {connectionId}");
                
                try
                {
                    var chatMessage = JsonSerializer.Deserialize<ChatMessage>(messageText);
                    if (chatMessage != null)
                    {
                        Console.WriteLine($"[DEBUG] 消息类型: {chatMessage.Type}, 发送者: {chatMessage.UserId}, 目标: {chatMessage.TargetUserId}");
                        await ProcessMessage(chatMessage, webSocket, connectionId);
                    }
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, "消息解析失败: {ConnectionId}", connectionId);
                    Console.WriteLine($"消息解析失败: {ex.Message}");
                    await SendResponse(webSocket, "error", false, "消息格式错误");
                }
            }
            else if (result.MessageType == WebSocketMessageType.Close)
            {
                logger.LogInformation("WebSocket连接关闭: {ConnectionId}", connectionId);
                break;
            }
        }
    }
    catch (Exception ex)
    {
        logger.LogError(ex, "WebSocket处理异常: {ConnectionId}", connectionId);
        Console.WriteLine($"WebSocket错误: {ex.Message}");
    }
    finally
    {
        await HandleDisconnect(connectionId);
    }
}

/// 处理消息 connectionId是当前连接的用户id  应该是要用目标用户id来发送消息
async Task ProcessMessage(ChatMessage message, WebSocket webSocket, string connectionId)
{
    switch (message.Type.ToLower())
    {
        case "register":
            await HandleRegister(message, webSocket, connectionId);
            break;
        case "login":
            await HandleLogin(message, webSocket, connectionId);
            break;
        case "private":
            await HandlePrivateMessage(message, connectionId);
            break;
        case "group":
            await HandleGroupMessage(message, connectionId);
            break;
        case "create_group":
            await HandleCreateGroup(message, connectionId);
            break;
        case "join_group":
            await HandleJoinGroup(message, connectionId);
            break;
        case "leave_group":
            await HandleLeaveGroup(message, connectionId);
            break;
        case "search_user":
            await HandleSearchUser(message, webSocket);
            break;
        case "get_groups":
            await HandleGetGroups(message, webSocket);
            break;
        default:
            await SendResponse(webSocket, "error", false, "未知消息类型");
            break;
    }
}

// 用户注册
async Task HandleRegister(ChatMessage message, WebSocket webSocket, string connectionId)
{
    if (string.IsNullOrEmpty(message.Username))
    {
        await SendResponse(webSocket, "register", false, "用户名不能为空");
        return;
    }

    // 使用connectionId作为userId（如果前端传了userId，connectionId就是userId）
    var userId = connectionId;
    
    var user = new User
    {
        UserId = userId,
        Username = message.Username,
        ConnectionId = connectionId,
        WebSocket = webSocket
    };

    users[userId] = user;
    userConnections[connectionId] = user;

    await SendResponse(webSocket, "register", true, "注册成功", new { UserId = userId, Username = message.Username });
    Console.WriteLine($"用户注册: {userId} - {message.Username}");
}

// 用户登录
async Task HandleLogin(ChatMessage message, WebSocket webSocket, string connectionId)
{
    // 使用前端传来的UserId，如果没有则使用connectionId
    var userId = !string.IsNullOrEmpty(message.UserId) ? message.UserId : connectionId;
    
    Console.WriteLine($"=== 用户登录调试 ===");
    Console.WriteLine($"登录请求 - UserId: {userId}, Username: {message.Username}, ConnectionId: {connectionId}");
    
    logger.LogBusinessOperation("用户登录请求", new { 
        UserId = userId, 
        Username = message.Username, 
        ConnectionId = connectionId 
    });
    
    if (!users.TryGetValue(userId, out var user))                                                               
    {
        // 如果用户不存在，创建新用户（自动注册）
        user = new User
        {
            UserId = userId,
            Username = message.Username ?? $"用户{userId.Substring(0, 8)}",
            ConnectionId = connectionId,
            WebSocket = webSocket,
            LoginTime = DateTime.Now
        };
        
        users[userId] = user;
        userConnections[connectionId] = user;
        
        Console.WriteLine($"自动注册新用户 - UserId: {userId}, Username: {user.Username}");
        
        logger.LogBusinessOperation("自动注册新用户", new { 
            UserId = userId, 
            Username = user.Username,
            ConnectionId = connectionId
        });
        Console.WriteLine($"自动注册新用户: {userId} - {user.Username}");
    }
    else
    {
        // 更新连接信息
        user.ConnectionId = connectionId;
        user.WebSocket = webSocket;
        user.LoginTime = DateTime.Now;
        userConnections[connectionId] = user;
        
        logger.LogBusinessOperation("用户重新登录", new { 
            UserId = userId, 
            Username = user.Username,
            ConnectionId = connectionId
        });
    }

    await SendResponse(webSocket, "login", true, "登录成功", new { 
        UserId = user.UserId, 
        Username = user.Username,
        JoinedGroups = user.JoinedGroups.ToList()
    });
    
    logger.LogBusinessOperation("用户登录成功", new { 
        UserId = user.UserId, 
        Username = user.Username,
        JoinedGroupsCount = user.JoinedGroups.Count
    });
    Console.WriteLine($"用户登录: {user.UserId} - {user.Username}");
}

// 处理私聊消息
async Task HandlePrivateMessage(ChatMessage message, string connectionId)
{
    logger.LogBusinessOperation("收到私聊消息请求", new { 
        ConnectionId = connectionId,
        TargetUserId = message.TargetUserId,
        ContentLength = message.Content?.Length ?? 0,
        ProductId = message.ProductId
    });

    // 调试：打印当前所有在线用户
    Console.WriteLine($"=== 调试信息 ===");
    Console.WriteLine($"当前在线用户数量: {users.Count}");
    foreach (var user in users)
    {
        Console.WriteLine($"用户ID: {user.Key}, 用户名: {user.Value.Username}, WebSocket状态: {user.Value.WebSocket?.State}");
    }
    Console.WriteLine($"===============");

    if (!userConnections.TryGetValue(connectionId, out var sender))
    {
        logger.LogWarning("发送者连接不存在: {ConnectionId}", connectionId);
        Console.WriteLine($"发送者连接不存在: {connectionId}");
        return;
    }

    Console.WriteLine($"发送者信息: UserId={sender.UserId}, Username={sender.Username}");

    if (string.IsNullOrEmpty(message.TargetUserId))
    {
        logger.LogWarning("目标用户ID为空, 发送者: {SenderId}", sender.UserId);
        await SendResponse(sender.WebSocket, "private", false, "目标用户ID不能为空");
        return;
    }

    Console.WriteLine($"查找目标用户: {message.TargetUserId}");

    if (!users.TryGetValue(message.TargetUserId, out var target))
    {
        logger.LogWarning("目标用户不存在: {TargetUserId}, 发送者: {SenderId}", message.TargetUserId, sender.UserId);
        Console.WriteLine($"目标用户不存在: {message.TargetUserId}");
        await SendResponse(sender.WebSocket, "private", false, "目标用户不存在");
        return;
    }

    Console.WriteLine($"目标用户信息: UserId={target.UserId}, Username={target.Username}, WebSocket状态={target.WebSocket?.State}");

    if (target.WebSocket?.State != WebSocketState.Open)
    {
        logger.LogWarning("目标用户不在线: {TargetUserId}, 发送者: {SenderId}", message.TargetUserId, sender.UserId);
        Console.WriteLine($"目标用户不在线: {message.TargetUserId}, WebSocket状态: {target.WebSocket?.State}");
        await SendResponse(sender.WebSocket, "private", false, "目标用户不在线");
        return;
    }

    // 发送给目标用户
    var targetMessage = new ChatMessage
    {
        Type = "private",
        UserId = sender.UserId,
        Username = sender.Username,
        Content = message.Content,
        TargetUserId = message.TargetUserId,
        MessageId = message.MessageId,  // 传递消息ID
        ProductId = message.ProductId,  // 传递商品ID
        Timestamp = DateTime.Now
    };

    Console.WriteLine($"准备发送消息给目标用户: {target.UserId}");
    Console.WriteLine($"消息内容: {JsonSerializer.Serialize(targetMessage)}");

    await SendMessage(target.WebSocket, targetMessage);
    
    Console.WriteLine($"消息已发送给目标用户: {target.UserId}");
    
    // 发送确认给发送者
    await SendResponse(sender.WebSocket, "private", true, "消息已发送", targetMessage);
    
    logger.LogBusinessOperation("私聊消息发送成功", new { 
        SenderId = sender.UserId,
        SenderName = sender.Username,
        TargetId = target.UserId,
        TargetName = target.Username,
        MessageId = message.MessageId,
        ProductId = message.ProductId
    });
    
    Console.WriteLine($"私聊消息: {sender.UserId} -> {target.UserId}");

    // 持久化到Redis
    try
    {
        var historyKey = GetHistoryKey(sender.UserId, target.UserId);
        var saved = new SavedMessage
        {
            MessageId = targetMessage.MessageId ?? Guid.NewGuid().ToString(),
            From = sender.UserId,
            To = target.UserId,
            Content = targetMessage.Content ?? string.Empty,
            ProductId = targetMessage.ProductId,
            Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds()
        };
        var json = JsonSerializer.Serialize(saved);
        await redisDb.ListRightPushAsync(historyKey, json);

        // 更新最近会话（双向）
        var nowScore = (double)DateTimeOffset.Now.ToUnixTimeMilliseconds();
        await redisDb.SortedSetAddAsync(GetRecentKey(sender.UserId), target.UserId, nowScore);
        await redisDb.SortedSetAddAsync(GetRecentKey(target.UserId), sender.UserId, nowScore);

        // 最新消息缓存（便于消息列表快速展示）
        await redisDb.StringSetAsync(GetLatestKey(sender.UserId, target.UserId), json);

        // 未读数：接收方+1
        await redisDb.HashIncrementAsync(GetUnreadHashKey(target.UserId), sender.UserId, 1);
    }
    catch (Exception ex)
    {
        logger.LogError(ex, "持久化聊天消息失败");
    }
}

// 处理群聊消息
async Task HandleGroupMessage(ChatMessage message, string connectionId)
{
    logger.LogBusinessOperation("收到群聊消息请求", new { 
        ConnectionId = connectionId,
        GroupId = message.GroupId,
        ContentLength = message.Content?.Length ?? 0
    });

    if (!userConnections.TryGetValue(connectionId, out var sender))
    {
        logger.LogWarning("发送者连接不存在: {ConnectionId}", connectionId);
        return;
    }

    if (string.IsNullOrEmpty(message.GroupId))
    {
        logger.LogWarning("群号为空, 发送者: {SenderId}", sender.UserId);
        await SendResponse(sender.WebSocket, "group", false, "群号不能为空");
        return;
    }

    if (!groups.TryGetValue(message.GroupId, out var group))
    {
        logger.LogWarning("群不存在: {GroupId}, 发送者: {SenderId}", message.GroupId, sender.UserId);
        await SendResponse(sender.WebSocket, "group", false, "群不存在");
        return;
    }

    if (!group.Members.Contains(sender.UserId))
    {
        logger.LogWarning("用户不在群中: {GroupId}, 发送者: {SenderId}", message.GroupId, sender.UserId);
        await SendResponse(sender.WebSocket, "group", false, "你不在该群中");
        return;
    }

    // 广播给群成员
    var groupMessage = new ChatMessage
    {
        Type = "group",
        UserId = sender.UserId,
        Username = sender.Username,
        Content = message.Content,
        GroupId = message.GroupId,
        GroupName = group.GroupName,
        Timestamp = DateTime.Now
    };

    var tasks = new List<Task>();
    foreach (var memberId in group.Members)
    {
        if (memberId != sender.UserId && users.TryGetValue(memberId, out var member) && 
            member.WebSocket?.State == WebSocketState.Open)
        {
            tasks.Add(SendMessage(member.WebSocket, groupMessage));
        }
    }

    await Task.WhenAll(tasks);
    await SendResponse(sender.WebSocket, "group", true, "消息已发送", groupMessage);
    
    logger.LogBusinessOperation("群聊消息发送成功", new { 
        SenderId = sender.UserId,
        SenderName = sender.Username,
        GroupId = message.GroupId,
        GroupName = group.GroupName,
        MemberCount = group.Members.Count,
        OnlineMemberCount = tasks.Count
    });
    
    Console.WriteLine($"群聊消息: {sender.UserId} -> 群{message.GroupId}");
}

// 创建群组
async Task HandleCreateGroup(ChatMessage message, string connectionId)
{
    if (!userConnections.TryGetValue(connectionId, out var creator))
    {
        return;
    }

    if (string.IsNullOrEmpty(message.GroupName))
    {
        await SendResponse(creator.WebSocket, "create_group", false, "群名称不能为空");
        return;
    }

    // 生成群号
    var groupId = Random.Shared.Next(100000, 999999).ToString();
    while (groups.ContainsKey(groupId))
    {
        groupId = Random.Shared.Next(100000, 999999).ToString();
    }

    var group = new Group
    {
        GroupId = groupId,
        GroupName = message.GroupName,
        CreatorId = creator.UserId
    };
    
    group.Members.Add(creator.UserId);
    creator.JoinedGroups.Add(groupId);
    groups[groupId] = group;

    await SendResponse(creator.WebSocket, "create_group", true, "群创建成功", new { 
        GroupId = groupId, 
        GroupName = message.GroupName 
    });
    
    Console.WriteLine($"创建群组: {groupId} - {message.GroupName} by {creator.UserId}");
}

// 加入群组
async Task HandleJoinGroup(ChatMessage message, string connectionId)
{
    if (!userConnections.TryGetValue(connectionId, out var user))
    {
        return;
    }

    if (string.IsNullOrEmpty(message.GroupId))
    {
        await SendResponse(user.WebSocket, "join_group", false, "群号不能为空");
        return;
    }

    if (!groups.TryGetValue(message.GroupId, out var group))
    {
        await SendResponse(user.WebSocket, "join_group", false, "群不存在");
        return;
    }

    if (group.Members.Contains(user.UserId))
    {
        await SendResponse(user.WebSocket, "join_group", false, "你已经在该群中");
        return;
    }

    group.Members.Add(user.UserId);
    user.JoinedGroups.Add(message.GroupId);

    await SendResponse(user.WebSocket, "join_group", true, "加入群成功", new { 
        GroupId = message.GroupId, 
        GroupName = group.GroupName 
    });

    // 通知群成员
    var joinMessage = new ChatMessage
    {
        Type = "system",
        Content = $"{user.Username} 加入了群聊",
        GroupId = message.GroupId,
        GroupName = group.GroupName,
        Timestamp = DateTime.Now
    };

    var tasks = new List<Task>();
    foreach (var memberId in group.Members)
    {
        if (memberId != user.UserId && users.TryGetValue(memberId, out var member) && 
            member.WebSocket?.State == WebSocketState.Open)
        {
            tasks.Add(SendMessage(member.WebSocket, joinMessage));
        }
    }
    await Task.WhenAll(tasks);
    
    Console.WriteLine($"用户 {user.UserId} 加入群 {message.GroupId}");
}

// 离开群组
async Task HandleLeaveGroup(ChatMessage message, string connectionId)
{
    if (!userConnections.TryGetValue(connectionId, out var user))
    {
        return;
    }

    if (string.IsNullOrEmpty(message.GroupId))
    {
        await SendResponse(user.WebSocket, "leave_group", false, "群号不能为空");
        return;
    }

    if (!groups.TryGetValue(message.GroupId, out var group))
    {
        await SendResponse(user.WebSocket, "leave_group", false, "群不存在");
        return;
    }

    if (!group.Members.Contains(user.UserId))
    {
        await SendResponse(user.WebSocket, "leave_group", false, "你不在该群中");
        return;
    }

    group.Members.Remove(user.UserId);
    user.JoinedGroups.Remove(message.GroupId);

    await SendResponse(user.WebSocket, "leave_group", true, "离开群成功");

    // 通知群成员
    var leaveMessage = new ChatMessage
    {
        Type = "system",
        Content = $"{user.Username} 离开了群聊",
        GroupId = message.GroupId,
        GroupName = group.GroupName,
        Timestamp = DateTime.Now
    };

    var tasks = new List<Task>();
    foreach (var memberId in group.Members)
    {
        if (users.TryGetValue(memberId, out var member) && 
            member.WebSocket?.State == WebSocketState.Open)
        {
            tasks.Add(SendMessage(member.WebSocket, leaveMessage));
        }
    }
    await Task.WhenAll(tasks);
    
    Console.WriteLine($"用户 {user.UserId} 离开群 {message.GroupId}");
}

// 搜索用户
async Task HandleSearchUser(ChatMessage message, WebSocket webSocket)
{
    if (string.IsNullOrEmpty(message.Content))
    {
        await SendResponse(webSocket, "search_user", false, "搜索内容不能为空");
        return;
    }

    var searchResults = users.Values
        .Where(u => u.UserId.Contains(message.Content) || u.Username.Contains(message.Content))
        .Select(u => new { u.UserId, u.Username })
        .Take(10)
        .ToList();

    await SendResponse(webSocket, "search_user", true, "搜索完成", searchResults);
}

// HTTP: 获取聊天历史（分页，默认limit=50，page从1开始）
app.MapGet("/api/chat/history/{userId}/{otherUserId}", async (string userId, string otherUserId, int? page, int? limit) =>
{
    var take = limit.GetValueOrDefault(50);
    var p = Math.Max(1, page.GetValueOrDefault(1));
    var key = GetHistoryKey(userId, otherUserId);
    var len = await redisDb.ListLengthAsync(key);
    if (len == 0) return Results.Ok(Array.Empty<SavedMessage>());

    // 从列表尾部向前分页
    long end = len - (p - 1) * take - 1;
    long start = Math.Max(0, end - take + 1);
    if (start > end) return Results.Ok(Array.Empty<SavedMessage>());

    var range = await redisDb.ListRangeAsync(key, start, end);
    var items = range.Select(v => JsonSerializer.Deserialize<SavedMessage>(v!)).Where(x => x != null)!
                     .OrderBy(x => x!.Timestamp)
                     .ToList();
    return Results.Ok(items);
});

// HTTP: 获取最近会话（含未读数，默认limit=50）
app.MapGet("/api/chat/recent/{userId}", async (string userId, int? limit) =>
{
    var take = limit.GetValueOrDefault(50);
    var zkey = GetRecentKey(userId);
    var entries = await redisDb.SortedSetRangeByRankWithScoresAsync(zkey, -take, -1, Order.Ascending);
    // entries 是按分值升序，从旧到新；我们倒序返回
    var list = new List<object>();
    foreach (var e in entries.Reverse())
    {
        var otherId = e.Element.ToString();
        var hkey = GetHistoryKey(userId, otherId);
        var last = await redisDb.ListGetByIndexAsync(hkey, -1);
        SavedMessage? latest = null;
        if (last.HasValue) latest = JsonSerializer.Deserialize<SavedMessage>(last!);
        var unread = await redisDb.HashGetAsync(GetUnreadHashKey(userId), otherId);
        list.Add(new
        {
            userId = otherId,
            latest,
            unread = unread.HasValue ? (int)unread : 0
        });
    }
    return Results.Ok(list);
});

// HTTP: 清除未读数
app.MapPost("/api/chat/unread/clear", async (ClearUnreadRequest req) =>
{
    if (string.IsNullOrEmpty(req.UserId) || string.IsNullOrEmpty(req.OtherUserId))
        return Results.BadRequest("参数错误");
    await redisDb.HashDeleteAsync(GetUnreadHashKey(req.UserId), req.OtherUserId);
    return Results.Ok(new { success = true });
});

// 获取用户加入的群组
async Task HandleGetGroups(ChatMessage message, WebSocket webSocket)
{
    if (string.IsNullOrEmpty(message.UserId))
    {
        await SendResponse(webSocket, "get_groups", false, "用户ID不能为空");
        return;
    }

    if (!users.TryGetValue(message.UserId, out var user))
    {
        await SendResponse(webSocket, "get_groups", false, "用户不存在");
        return;
    }

    var userGroups = user.JoinedGroups
        .Where(groupId => groups.ContainsKey(groupId))
        .Select(groupId => groups[groupId])
        .Select(g => new { g.GroupId, g.GroupName, MemberCount = g.Members.Count })
        .ToList();

    await SendResponse(webSocket, "get_groups", true, "获取群组成功", userGroups);
}

// 处理断开连接
async Task HandleDisconnect(string connectionId)
{
    Console.WriteLine($"[DEBUG] 处理断开连接: {connectionId}");
    
    if (userConnections.TryRemove(connectionId, out var user))
    {
        // 同时从users字典中移除用户信息，避免保留无效连接
        users.TryRemove(user.UserId, out _);
        
        Console.WriteLine($"[DEBUG] 用户已从连接池中移除: UserId={user.UserId}, Username={user.Username}");
        
        logger.LogBusinessOperation("用户断开连接", new { 
            UserId = user.UserId,
            Username = user.Username,
            ConnectionId = connectionId,
            LoginDuration = DateTime.Now - user.LoginTime
        });
        Console.WriteLine($"用户断开连接: {user.UserId} - {user.Username}");
    }
    else
    {
        Console.WriteLine($"[DEBUG] 尝试断开不存在的连接: {connectionId}");
        logger.LogWarning("尝试断开不存在的连接: {ConnectionId}", connectionId);
    }
    await Task.CompletedTask;
}

// 发送响应
async Task SendResponse(WebSocket webSocket, string type, bool success, string message, object? data = null)
{
    var response = new ResponseMessage
    {
        Type = type,
        Success = success,
        Message = message,
        Data = data
    };

    await SendMessage(webSocket, response);
}

// 发送消息
async Task SendMessage(WebSocket webSocket, object message)
{
    try
    {
        if (webSocket.State == WebSocketState.Open)
        {
            var json = JsonSerializer.Serialize(message);
            var buffer = Encoding.UTF8.GetBytes(json);
            await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
            
            // 记录消息发送成功日志
            if (message is ChatMessage chatMsg && !string.IsNullOrEmpty(chatMsg.TargetUserId))
            {
                logger.LogInformation("业务操作: 消息成功发送到目标用户", new
                {
                    Operation = "消息成功发送到目标用户",
                    Data = new
                    {
                        TargetUserId = chatMsg.TargetUserId,
                        MessageId = chatMsg.MessageId,
                        MessageType = chatMsg.Type,
                        WebSocketState = webSocket.State.ToString()
                    }
                });
            }
        }
        else
        {
            // 记录WebSocket状态异常日志
            if (message is ChatMessage chatMsg && !string.IsNullOrEmpty(chatMsg.TargetUserId))
            {
                logger.LogWarning("业务操作: WebSocket连接状态异常，消息发送失败", new
                {
                    Operation = "WebSocket连接状态异常，消息发送失败",
                    Data = new
                    {
                        TargetUserId = chatMsg.TargetUserId,
                        MessageId = chatMsg.MessageId,
                        WebSocketState = webSocket.State.ToString()
                    }
                });
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"发送消息失败: {ex.Message}");
        
        // 记录消息发送异常日志
        if (message is ChatMessage chatMsg && !string.IsNullOrEmpty(chatMsg.TargetUserId))
        {
            logger.LogError("业务操作: 消息发送异常", new
            {
                Operation = "消息发送异常",
                Data = new
                {
                    TargetUserId = chatMsg.TargetUserId,
                    MessageId = chatMsg.MessageId,
                    ErrorMessage = ex.Message,
                    WebSocketState = webSocket.State.ToString()
                }
            });
        }
    }
}

// 从环境变量或配置读取URL，Docker中会设置ASPNETCORE_URLS
app.Run();

// 用户信息
public class User
{
    public string UserId { get; set; } = string.Empty; // 唯一账号
    public string Username { get; set; } = string.Empty; // 显示名称
    public string ConnectionId { get; set; } = string.Empty;
    public WebSocket WebSocket { get; set; } = null!;
    public DateTime LoginTime { get; set; } = DateTime.Now;
    public HashSet<string> JoinedGroups { get; set; } = new();
}

// 群组信息
public class Group
{
    public string GroupId { get; set; } = string.Empty; // 唯一群号
    public string GroupName { get; set; } = string.Empty;
    public string CreatorId { get; set; } = string.Empty;
    public DateTime CreateTime { get; set; } = DateTime.Now;
    public HashSet<string> Members { get; set; } = new();
}

// 消息类型
public class ChatMessage
{
    public string Type { get; set; } = string.Empty; // "register", "login", "private", "group", "create_group", "join_group", "leave_group"
    public string UserId { get; set; } = string.Empty; //连接用户
    public string Username { get; set; } = string.Empty;
    public string Content { get; set; } = string.Empty;
    public string? TargetUserId { get; set; } // 私聊目标用户ID
    public string? GroupId { get; set; } // 群聊群号
    public string? GroupName { get; set; } // 群名称
    public string? MessageId { get; set; } // 消息ID
    public string? ProductId { get; set; } // 商品ID（用于商品相关的聊天）
    public DateTime Timestamp { get; set; } = DateTime.Now;
}

public class SavedMessage
{
    public string? MessageId { get; set; }
    public string From { get; set; } = string.Empty;
    public string To { get; set; } = string.Empty;
    public string Content { get; set; } = string.Empty;
    public string? ProductId { get; set; }
    public long Timestamp { get; set; }
}

public class ClearUnreadRequest
{
    public string UserId { get; set; } = string.Empty;
    public string OtherUserId { get; set; } = string.Empty;
}

// 响应消息
public class ResponseMessage
{
    public string Type { get; set; } = string.Empty;
    public bool Success { get; set; }
    public string Message { get; set; } = string.Empty;
    public object? Data { get; set; }
}